﻿#--------------------------------------------#
# Server Side OpenChat script                #
# a script that implements a chatting engine #
# Written by : Ryno Kotzé                    #
#        aka : ravencoder/lemonxah           #
#--------------------------------------------#


#--------------------------------------------#
#        Implemented Chat commands           #
#--------------------------------------------#
'''
commands that reach the server will not be /
pre-pended that is a client side function to 
differentiate between normal chat and commands

    help # displays this help
    global <msg> # send message to all users connected
    channel <channel name> <msg> # send message to all users that joined that channel
    createchannel <channel name> # create channel
    join <channel name> # join channel
    part <channel name> # leave a channel you have previously subscribed to
    msg <nick> <msg> # send a private message
    nick <nick> # To change your nickname
    poke <nick> # pokes a client to let him know someone is looking for him.

for now these are the commands that will be 
implemented
'''
#--------------------------------------------#
#         Impports                           #
#--------------------------------------------#
import clr
clr.AddReference("System.Core")
import System
from System.Collections.Generic import List, Dictionary
from System.Collections import *
clr.ImportExtensions(System.Linq)

if msg.Header.MessageType == 'OpenChat':
    if env == 'server':
        helpmsg = '\nCommands help:\n\n/help # displays this help\n/global <msg> # send message to all users connected'
        helpmsg += '\n/channel <channel name> <msg> # send message to all users that joined that channel'
        helpmsg += '\n/createchannel <channel name> # create channel'
        helpmsg += '\n/join <channel name> # join channel'
        helpmsg += '\n/part <channel name> # leave a channel you have previously subscribed to'
        helpmsg += '\n/msg <nick> <msg> # send a private message'
        helpmsg += '\n/nick <nick> # To change your nickname'
        helpmsg += '\n/poke <nick> # pokes a client to let him know someone is looking for him.'
        helpmsg += '\n/list # Lists all connected clients.'
        helpmsg += '\n/clist # Lists all channels.\n\n'
        #print 'Server Script'
        # setting up the Channel list in the vars
        channels = Dictionary[str, List[str]]()
        if vars.ContainsKey('channels') == False:
            vars.Add('channels', channels)
        else :
            channels = vars['channels']
        #Console.WriteLine('{0}, channels', channels.Count)
        #--------------------------------------------#
        #                                            #
        #--------------------------------------------#
        cmd, rest = msg.Body[0:msg.Body.IndexOf(' ')].ToLower(), msg.Body[msg.Body.IndexOf(' ')+1:]
        cname = 'unknown'
        if svr.Name is not None:
            if not svr.Name == '':
                cname = svr.Name
        if not msg.Body.Contains(' '): cmd = msg.Body
        if cmd == 'global':
            # svr.Parent.Clients all clients that is connected
            for c in svr.Parent.Clients:
                if svr.Name == c.Name:
                    pass
                else:
                    c.Send(msg.Header, '::global:'+cname+'::' + rest)
        elif cmd == 'clist':
            clist = ''
            for c in channels:
                clist+=c.Key+', '
            svr.Send(msg.Header, '\n::Channel List::\n'+clist)
        elif cmd == 'list':
            clients = ''
            for c in svr.Parent.Clients:
                ccname = 'unknown'
                if c.Name is not None:
                    if not c.Name == '':
                        ccname = c.Name
                clients += '\n'+ccname+'::'+c.GUID.ToString()
            clients += '\n'
            svr.Send(msg.Header, '\n::Client List::' + clients)
        elif cmd == 'help':
            svr.Send(msg.Header, helpmsg)
        elif cmd == 'channel':
            chname, m = rest[0:rest.IndexOf(' ')], rest[rest.IndexOf(' ')+1:]
            if channels.ContainsKey(chname):
                for c in svr.Parent.Clients:
                    if channels[chname].Contains(c.GUID.ToString()):
                        c.Send(msg.Header, '::'+chname+':'+cname+'::' + m)
            else:
                svr.Send(msg.Header, 'Channel does not exist')
        elif cmd == 'nick':
            newnick = rest
            if svr.Parent.Clients.Any(lambda c: c.Name == newnick):
                svr.Send(msg.Header, 'Nickname is not available')
            else:
                svr.Name = newnick
        elif cmd == 'createchannel':
            chname = rest
            if channels.ContainsKey(chname):
                svr.Send(msg.Header, 'Channel already exists')
            else:
                channels.Add(chname, List[str]())
                channels[chname].Add(svr.GUID.ToString())
        elif cmd == 'join':
            chname = rest
            if channels.ContainsKey(chname):
                if channels[chname].Contains(svr.GUID.ToString()):
                    svr.Send(msg.Header, 'You are already in this channel')
                else:
                    channels[chname].Add(svr.GUID.ToString())
            else:
                svr.Send(msg.Header, 'Channel does not exist')
        elif cmd == 'msg':
            to, m = rest[0:rest.IndexOf(' ')], rest[rest.IndexOf(' ')+1:]
            for c in svr.Parent.Clients:
                if c.Name == to:
                    c.Send(msg.Header, '::' + cname + '::' + m)
                    break
                else:
                    svr.Send(msg.Header, 'Client does not exist')
        elif cmd == 'poke':
            to = rest
            for c in svr.Parent.Clients:
                if c.Name == to:
                    c.Send(msg.Header, '~::p0åk3::~')
                    break
                else:
                    svr.Send(msg.Header, 'Client does not exist')
        elif cmd == 'part':
            chname = rest
            if channels.ContainsKey(chname):
                channels[chname].Remove(svr.GUID.ToString())
            else:
                svr.Send(msg.Header, 'Channel does not exist')
        else:
            svr.Send(msg.Header, 'Command does not exist')
    elif env == 'client':
        print msg.Body.ToString()
    else:
        pass    
else:
    pass
#--------------------------------------------#
#                                            #
#--------------------------------------------#